package cn.bbstone.pisces2.client.handler;

import cn.bbstone.pisces2.client.base.ClientCache;
import cn.bbstone.pisces2.client.task.impl.FileTask;
import cn.bbstone.pisces2.client.task.impl.FileTaskListener;
import cn.bbstone.pisces2.client.util.MsgUtil;
import cn.bbstone.pisces2.comm.BFileCmd;
import cn.bbstone.pisces2.proto.rsp.RspFile;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class RspFileInfoHandler implements ClientHandler {
    private static Logger log = LoggerFactory.getLogger(RspFileInfoHandler.class);

    public RspFileInfoHandler() {
    }

    @Override
    public void handle(ChannelHandlerContext ctx, RspFile rspFile) {
        String msgId = rspFile.getMsgId();
        Byte msgType = rspFile.getMsgType();
        long fileNo = rspFile.getFileNo();
        log.debug("msg id: {}, msgType: {}, fileNo: {}", msgId, msgType, fileNo);
        //
        FileTask fileTask = ClientCache.getTask(fileNo);
        if (fileTask == null) {
            // save fli.idx file info
            fileTask = new FileTask(rspFile);
            ClientCache.addTask(fileNo, fileTask);
            fileTask.addListner(new FileTaskListener());

//            // send REQ_LIST_INFO_ACK & REQ_FILE_DATA request
            handleNext(ctx, rspFile, fileTask);

        }

    }

    @Override
    public void handleNext(ChannelHandlerContext ctx, RspFile rspFile, FileTask fileTask) {

        // check if client exist the file, skip req file data
        boolean skipFile = fileTask.isFileSkip();
        // not overwrite & client file exists, skip file
        if (skipFile) {
            // send REQ_FILE_INFO_SKIP_ACK
            log.info("send FILE INFO SKIP ACK, fileNo: {}", rspFile.getFileNo());
            ByteBuf out = MsgUtil.buildReq(BFileCmd.REQ_FILE_INFO_SKIP_ACK, rspFile.getFileNo());
            ctx.writeAndFlush(out);
            // clean update cache & update savepoint file
            fileTask.fireSkipEvent();
            MsgUtil.reqNextFileInfo(ctx);
            return;
        }
        // send REQ_LIST_INFO_ACK
        log.debug("send FILE INFO ACK, fileNo: {}", rspFile.getFileNo());
        ByteBuf out = MsgUtil.buildReq(BFileCmd.REQ_FILE_INFO_ACK, rspFile.getFileNo());
        ctx.writeAndFlush(out);
        // send REQ_FILE_DATA
        log.debug("send first chunk of FILE(fileNo: {}) data.", rspFile.getFileNo());
        ByteBuf out2 = MsgUtil.buildReq(BFileCmd.REQ_FILE_DATA, rspFile.getFileNo());
        ctx.writeAndFlush(out2);
    }

}
